import cplex.callbacks as CPX_CB

class check_bigm_at_incumbent(CPX_CB.IncumbentCallback):
    def __call__(self):
        print "\n"
        if self.fc.flag == 1:
            #self.times_called += 1
            x_val = self.get_values(self.fc.x_name)
            y_val = self.get_values(self.fc.y_name)
            slacks = [self.get_linear_slacks(self.fc.M_rowname[i]) for i in self.fc.I]
            M_inc_list = []
            print y_val
            for i in self.fc.I:
                if self.fc.M_rank[i] > self.fc.NS-self.fc.RLB:
                    continue

                for s in self.fc.S:
                    if  abs(y_val[s]) > 0.00001 and abs(slacks[i][s]) < 0.0001:
                        M_inc_list += [i]
                        
                        break

            if len(M_inc_list) == 0:
                self.fc.flag = 1
                print "M valid at this node", M_inc_list
            else:
                self.fc.flag = 0
                for i in M_inc_list:
                    self.fc.M_rank[i] += 1
                print "M too small, resolve"
                #self.abort()

class check_bigm_at_branch(CPX_CB.BranchCallback):
    def __call__(self):
        print "\n"
        if self.fc.flag == 1:
            #self.times_called += 1
            x_val = self.get_values(self.fc.x_name)
            y_val = self.get_values(self.fc.y_name)
            slacks = [self.get_linear_slacks(self.fc.M_rowname[i]) for i in self.fc.I]
            M_inc_list = []
            print y_val
            for i in self.fc.I:
                if self.fc.M_rank[i] > self.fc.NS-self.fc.RLB:
                    continue

                for s in self.fc.S:
                    if  abs(y_val[s]) > 0.0001 and abs(slacks[i][s]) < 0.0001:
                        M_inc_list += [i]
                        
                        break

            if len(M_inc_list) == 0:
                self.fc.flag = 1
                print "M valid at this node", M_inc_list
            else:
                self.fc.flag = 0
                for i in M_inc_list:
                    self.fc.M_rank[i] += 1
                print "M too small, resolve"
                #self.abort()
                

